package service

import (
	ClickHouse "gin/database"
	"gin/model"
	"gin/types"
	"github.com/gin-gonic/gin"
	"time"
)

type WorkTime struct {
}

// 租户成员工时timelog修正统计
func (t WorkTime) GetTenantUserStatistics(tenantId int64, projectIdList []int64, dateStart string, dateEnd string, departmentId int64, roleCode string, userId []int64, ctx *gin.Context) (res []types.GetTenantUserWorkTimeStatisticsResItem, err error) {
	var roleCodes []string
	var departmentIds []uint64
	if departmentId != 0 || roleCode != "" {
		if departmentId != 0 {
			departmentIds = append(departmentIds, uint64(departmentId))
		}
		if roleCode != "" {
			roleCodes = append(roleCodes, roleCode)
		}

	} else {
		////查询当前所属当前租户的所有部门
		var DepartmentService Department
		departmentListQueryRes, errs := DepartmentService.getDepartmentList(tenantId, nil)

		if errs != nil {
			err = errs
			return
		}

		// 部门 ids
		for _, departmentItem := range departmentListQueryRes {
			res = append(res, types.GetTenantUserWorkTimeStatisticsResItem{
				Id:           departmentItem.Id,
				Name:         departmentItem.Name,
				Type:         "department",
				ParentId:     departmentItem.ParentId,
				WorkHour:     0,
				TaskWorkHour: 0,
			})
			departmentIds = append(departmentIds, departmentItem.Id)
		}
	}

	query := ClickHouse.DB.Model(&model.WorkTimeRecord{}).Where("tenant_id = ?", tenantId)
	if len(projectIdList) > 0 {
		query.Where("project_id in ?", projectIdList)
	}
	if dateStart != "" {
		timeStart, errs := time.ParseInLocation("2006-01-02", dateStart, time.Local)
		if errs != nil {
			err = errs
			return nil, err
		}
		query.Where("record_time >= ?", timeStart.Unix())
	}
	if dateEnd != "" {
		timeEnd, errs := time.ParseInLocation("2006-01-02", dateEnd, time.Local)
		if errs != nil {
			return nil, errs
		}
		query.Where("record_time <= ?", timeEnd.Unix())
	}

	var userWorkTimeRes []types.UserWorkTimeSumRes
	err = query.Select("sum(work_time) AS work_time,user_id").Group("user_id").Find(&userWorkTimeRes).Error
	if err != nil {
		return
	}
	var userWorkTimeResMap = make(map[uint64]*types.UserWorkTimeSumRes, 0)
	for i, re := range userWorkTimeRes {
		userWorkTimeResMap[re.UserId] = &userWorkTimeRes[i]
	}

	// 获取部门下的用户
	// 获取指定租户下面所有用户及其角色标签
	var UserService User
	WorkHourService := WorkHour{}
	if departmentId != 0 || roleCode != "" {
		var userList []model.User
		if departmentId != 0 {
			userList, err = UserService.ByDepartmentOrRoleSelectUser(departmentIds, roleCodes, []int64{}, userId)
			if err != nil {
				return
			}
		}

		if roleCode != "" {
			userList, err = UserService.ByDepartmentOrRoleSelectUser([]uint64{}, roleCodes, []int64{tenantId}, userId)
			if err != nil {
				return
			}
		}

		var imUserIdList []uint64
		for _, userItem := range userList {
			imUserIdList = append(imUserIdList, uint64(userItem.UnionId))
		}

		workHourMap, errss := WorkHourService.QueryUserWorkHour(imUserIdList, dateStart+" 00:00:00", dateEnd+" 00:00:00", ctx)
		if errss != nil {
			err = errss
			return
		}

		var tmpWorkTime uint64
		var tmpWorkHour float64
		for _, userItem := range userList {
			tmpWorkTime = 0
			tmpWorkHour = 0.00
			if _, ok := userWorkTimeResMap[userItem.Id]; ok {
				tmpWorkTime = userWorkTimeResMap[userItem.Id].WorkTime
			}
			if _, ok := workHourMap[uint64(userItem.UnionId)]; ok {
				tmpWorkHour = workHourMap[uint64(userItem.UnionId)]
			}

			res = append(res, types.GetTenantUserWorkTimeStatisticsResItem{
				Id:           userItem.Id,
				Name:         userItem.Name,
				Type:         "user",
				ParentId:     0,
				WorkHour:     tmpWorkHour,
				TaskWorkHour: Decimal(float64(tmpWorkTime) / 3600),
				ImUserId:     uint64(userItem.UnionId),
			})
		}

	} else {
		departmentUsers, distinctUserIds, errors := UserService.GetDepartmentUserMultiDepartmentUser(departmentIds, tenantId)
		if errors != nil {
			err = errors
			return
		}

		var userService User
		imUserIdList, errorss := userService.GetUnionIdListByUserIdList(distinctUserIds)
		if errorss != nil {
			err = errorss
			return
		}

		workHourMap, errs := WorkHourService.QueryUserWorkHour(imUserIdList, dateStart+" 00:00:00", dateEnd+" 00:00:00", ctx)
		if errs != nil {
			err = errs
			return
		}
		var tmpWorkTime uint64
		var tmpWorkHour float64

		var tenantNameGroupMap = make(map[uint64]string)
		for _, departmentUserItem := range departmentUsers {
			tmpWorkTime = 0
			tmpWorkHour = 0.00
			if _, ok := userWorkTimeResMap[departmentUserItem.UserId]; ok {
				tmpWorkTime = userWorkTimeResMap[departmentUserItem.UserId].WorkTime
			}
			if _, ok := workHourMap[departmentUserItem.UnionId]; ok {
				tmpWorkHour = workHourMap[departmentUserItem.UnionId]
			}

			res = append(res, types.GetTenantUserWorkTimeStatisticsResItem{
				Id:           departmentUserItem.UserId,
				Name:         departmentUserItem.UserName,
				Type:         "user",
				ParentId:     departmentUserItem.DepartmentId,
				WorkHour:     tmpWorkHour,
				TaskWorkHour: Decimal(float64(tmpWorkTime) / 3600),
			})
			tenantNameGroupMap[departmentUserItem.TenantId] = departmentUserItem.TenantName
		}
	}

	return
}

// ExportStatistics 导出工时报表
func (t WorkTime) ExportStatistics(tenantId int64, projectIdList []int64, dateStart string, dateEnd string, page []int, ctx *gin.Context) (res []types.ExportWorkTimeStatisticsResItem, err error) {

	query := ClickHouse.DB.Model(&model.WorkTimeRecord{}).Where("tenant_id = ?", tenantId)
	if len(projectIdList) > 0 {
		query.Where("project_id in ?", projectIdList)
	}
	if dateStart != "" {
		timeStart, err := time.ParseInLocation("2006-01-02", dateStart, time.Local)
		if err != nil {
			return nil, err
		}
		query.Where("record_time >= ?", timeStart.Unix())
	}
	if dateEnd != "" {
		timeEnd, err := time.ParseInLocation("2006-01-02", dateEnd, time.Local)
		if err != nil {
			return nil, err
		}
		query.Where("record_time <= ?", timeEnd.Unix())
	}

	var userWorkTimeRes []types.UserWorkTimeSumRes
	err = query.Select("sum(work_time) AS work_time,user_id").Group("user_id").Find(&userWorkTimeRes).Error
	if err != nil {
		return
	}
	userIdList := make([]uint64, 0)
	distinctUserIds := make([]uint64, 0)
	var userWorkTimeResMap = make(map[uint64]*types.UserWorkTimeSumRes, 0)
	for i, re := range userWorkTimeRes {
		userWorkTimeResMap[re.UserId] = &userWorkTimeRes[i]
		userIdList = append(userIdList, re.UserId)
	}

	// 获取所有用户
	var UserService User
	userList, userListErr := UserService.GetUserListPage(ClickHouse.DB.Where("id > 0"), page)
	if userListErr != nil {
		return
	}
	for _, v := range userList {
		distinctUserIds = append(distinctUserIds, v.Id)
	}

	var userService User
	imUserIdList, imUserIdListErr := userService.GetUnionIdListByUserIdList(distinctUserIds)
	if imUserIdListErr != nil {
		return
	}
	WorkHourService := WorkHour{}
	workHourMap, workHourMapErr := WorkHourService.QueryUserWorkHour(imUserIdList, dateStart+" 00:00:00", dateEnd+" 00:00:00", ctx)
	if workHourMapErr != nil {
		return
	}

	var tmpWorkTime uint64
	var tmpWorkHour float64
	for _, Item := range userList {
		tmpWorkTime = 0
		tmpWorkHour = 0.00
		if _, ok := userWorkTimeResMap[Item.Id]; ok {
			tmpWorkTime = userWorkTimeResMap[Item.Id].WorkTime
		}
		if _, ok := workHourMap[uint64(Item.UnionId)]; ok {
			tmpWorkHour = workHourMap[uint64(Item.UnionId)]
		}
		res = append(res, types.ExportWorkTimeStatisticsResItem{
			Id:           Item.Id,
			Name:         Item.Name,
			WorkHour:     tmpWorkHour,
			TaskWorkHour: Decimal(float64(tmpWorkTime) / 3600),
		})
	}
	return
}
